package org.rambadger.command.resource;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.yammer.dropwizard.auth.Auth;
import com.yammer.dropwizard.views.View;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.mindrot.jbcrypt.BCrypt;
import org.mongojack.DBCursor;
import org.mongojack.DBQuery;
import org.mongojack.JacksonDBCollection;
import org.rambadger.command.auth.AuthUser;
import org.rambadger.command.axon.JCollection;
import org.rambadger.command.command.CreateAdminUser;
import org.rambadger.command.command.RegisterNewUser;
import org.rambadger.command.view.RegisterUserForm;

import javax.validation.Valid;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

@Path("/registeruser")
public class RegisterUserResource {
    private @Context CommandGateway gateway = null;

    @JCollection(type=AuthUser.class)
    private JacksonDBCollection<AuthUser, String> authUsers = null;

    public static class UserSubmissionJSON {
        @Valid @NotEmpty @JsonProperty
        String username;
        @Valid @NotEmpty @Email @JsonProperty
        String emailAddress;
        @Valid @NotEmpty @JsonProperty
        String password;
        @JsonProperty
        String firstName;
        @JsonProperty
        String lastName;
        @JsonProperty
        boolean isAdmin;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public void registerUser(@Auth(required = false) AuthUser user, @Valid UserSubmissionJSON newUserData) {
        DBCursor<AuthUser> found = authUsers.find(DBQuery.is("hasSystemAdmin", true));
        if (newUserData.firstName == null) newUserData.firstName = "";
        if (newUserData.lastName == null) newUserData.lastName = "";
        //TODO: Check formatting of stuff
        if (found.count() == 0 || user.hasAdmin()){
        String hash = BCrypt.hashpw(newUserData.password, BCrypt.gensalt());
        if (newUserData.isAdmin)
            gateway.send(new CreateAdminUser(newUserData.username, hash, newUserData.emailAddress, newUserData.firstName, newUserData.lastName));

        else
            gateway.send(new RegisterNewUser(newUserData.username, hash, newUserData.emailAddress, newUserData.firstName, newUserData.lastName));
        }
    }
    @GET
    @Produces(MediaType.TEXT_HTML)
    public View getUserForm(@Auth(required = true) AuthUser user) {
        return new RegisterUserForm(user);
    }

}
